package ar.edu.itba.it.cg.grupo01.utils;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Scanner;

import com.jme.bounding.BoundingBox;
import com.jme.image.Texture;
import com.jme.math.Vector3f;
import com.jme.scene.Node;
import com.jme.scene.Spatial;
import com.jme.scene.state.ZBufferState;
import com.jme.scene.state.ZBufferState.TestFunction;
import com.jme.system.DisplaySystem;
import com.jme.util.TextureManager;
import com.jme.util.export.binary.BinaryImporter;
import com.jme.util.resource.ResourceLocatorTool;
import com.jme.util.resource.SimpleResourceLocator;

/**
 * Helper class for loading models and other stuff. Currently only loads JME
 * binary models, but it's easily customizable for loading other types.
 * 
 * @author Erick B Passos
 */
@SuppressWarnings("deprecation")
public class Utils {

	// So JME can find the model textures easily.
	private static URL resourceSearchPath;
	private static URL textureSearchPath;
	private static URL modelSearchPath;

	static {
		java.io.File data = new java.io.File("./data");
		java.io.File textures = new java.io.File("./data/textures");
		java.io.File models = new java.io.File("./data/models");
		// resourceSearchPath = Utils.class.getResource( "data/" );
		try {
			resourceSearchPath = data.toURL();
			textureSearchPath = textures.toURL();
			modelSearchPath = models.toURL();
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		try {
			ResourceLocatorTool.addResourceLocator(
					ResourceLocatorTool.TYPE_TEXTURE,
					new SimpleResourceLocator(resourceSearchPath));
			ResourceLocatorTool.addResourceLocator(
					ResourceLocatorTool.TYPE_TEXTURE,
					new SimpleResourceLocator(textureSearchPath));
			ResourceLocatorTool.addResourceLocator(
					ResourceLocatorTool.TYPE_MODEL, new SimpleResourceLocator(
							modelSearchPath));
			ResourceLocatorTool.addResourceLocator(
					ResourceLocatorTool.TYPE_TEXTURE,
					new SimpleResourceLocator(modelSearchPath));
		} catch (URISyntaxException e1) {
			e1.printStackTrace();
		}
	}

	public static URL getResourceURL(String relativePath) {
		try {
			return new URL(resourceSearchPath, relativePath);
		} catch (MalformedURLException e) {
			throw new IllegalArgumentException(e);
		}
	}

	/**
	 * Loads a jme binary model from file, creating a bounding box for it.
	 * 
	 * @param path
	 *            to jme file
	 * @return loaded model, null on error
	 */
	public static Node loadModel(String path) {
		Node node = null;
		URL modelURL = null;
		try {
			modelURL = new URL(resourceSearchPath, path);
			BufferedInputStream stream = new BufferedInputStream(modelURL
					.openStream());
			node = new Node();
			Spatial model = (Spatial) BinaryImporter.getInstance().load(stream);
			node.attachChild(model);
			node.setModelBound(new BoundingBox());
			node.updateModelBound();
		} catch (IOException e) {
			System.out.println("Could not load model '" + modelURL + "'");
		}

		return node;
	}

	public static Texture loadTexture(String path) {
		Texture texture = null;
		URL textureURL = null;
		try {
			textureURL = new URL(resourceSearchPath, path);
			// BufferedInputStream stream = new
			// BufferedInputStream(textureURL.openStream());
			texture = TextureManager.loadTexture(textureURL,
					Texture.MinificationFilter.NearestNeighborLinearMipMap,
					Texture.MagnificationFilter.NearestNeighbor);
		} catch (IOException e) {
			System.out.println("Could not open texture '" + textureURL + "'");
			return null;
		}

		return texture;
	}

	/**
	 * Helper method to apply a ZBufferState to a node.
	 * 
	 * @param node
	 *            where to apply to
	 */
	public static void applyZBuffer(Node node) {
		ZBufferState zbuf = DisplaySystem.getDisplaySystem().getRenderer()
				.createZBufferState();
		zbuf.setWritable(false);
		zbuf.setEnabled(true);
		zbuf.setFunction(TestFunction.LessThanOrEqualTo);
		node.setRenderState(zbuf);
	}

	private static String resolveName(String name) {
		if (name == null) {
			return name;
		}
		if (!name.startsWith("/")) {
			Class<?> c = Utils.class;
			while (c.isArray()) {
				c = c.getComponentType();
			}
			String baseName = c.getName();
			int index = baseName.lastIndexOf('.');
			if (index != -1) {
				name = baseName.substring(0, index).replace('.', '/') + "/"
						+ name;
			}
		} else {
			name = name.substring(1);
		}
		return name;
	}

	public static Vector3f getPosition(String pos) {

		float x, y, z;

		Scanner s = new Scanner(pos.replaceAll("\\s", ""));
		s.useDelimiter(",");

		x = s.nextFloat();
		y = s.nextFloat();
		z = s.nextFloat();

		return new Vector3f(x, y, z);
	}
}
